<!doctype html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/blog/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="区块链,solidity,智能合约," />








  <link rel="shortcut icon" type="image/x-icon" href="/blog/favicon.ico?v=5.1.0" />






<meta name="description" content="前段时间了解了一下智能合约的开发，部署运行。本文中介一下前段时间的成果。如果存在某些纰漏还行各位大神指正批评 智能合约开发在智能合约的开发中，我选择的是Ethereum的solidity。当然还有其他的开发语言如： 语言入门对于solidity语言的入门可以参照一下一些教程  solidity的官方教程。 etherrum提供了一套完整的实例项目。从发布自己的代币，到众筹项目的开发也是不错的参考教">
<meta name="keywords" content="区块链,solidity,智能合约">
<meta property="og:type" content="article">
<meta property="og:title" content="创建合约项目与合约交互">
<meta property="og:url" content="https://gitee.com/shuhao/2018/11/24/geth创建合约项目与合约交互/index.html">
<meta property="og:site_name" content="Niki">
<meta property="og:description" content="前段时间了解了一下智能合约的开发，部署运行。本文中介一下前段时间的成果。如果存在某些纰漏还行各位大神指正批评 智能合约开发在智能合约的开发中，我选择的是Ethereum的solidity。当然还有其他的开发语言如： 语言入门对于solidity语言的入门可以参照一下一些教程  solidity的官方教程。 etherrum提供了一套完整的实例项目。从发布自己的代币，到众筹项目的开发也是不错的参考教">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_compile.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_deploy_1.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_deploy_2.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_deploy_pending.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_deplou.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_deploy_info.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/use_infura.png">
<meta property="og:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_method_hash.png">
<meta property="og:updated_time" content="2019-02-16T06:55:31.152Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="创建合约项目与合约交互">
<meta name="twitter:description" content="前段时间了解了一下智能合约的开发，部署运行。本文中介一下前段时间的成果。如果存在某些纰漏还行各位大神指正批评 智能合约开发在智能合约的开发中，我选择的是Ethereum的solidity。当然还有其他的开发语言如： 语言入门对于solidity语言的入门可以参照一下一些教程  solidity的官方教程。 etherrum提供了一套完整的实例项目。从发布自己的代币，到众筹项目的开发也是不错的参考教">
<meta name="twitter:image" content="https://gitee.com/blog/images/区块链/smart_contract/remix_compile.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Mist',
    sidebar: {"position":"right","display":"post","offset":12,"offset_float":0,"b2t":false,"scrollpercent":false},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://gitee.com/shuhao/2018/11/24/geth创建合约项目与合约交互/"/>





  <title> 创建合约项目与合约交互 | Niki </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  





  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?cb9f0585e406f878cb2f29c89ad3cdb7";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>










  
  
    
  

  <div class="container one-collumn sidebar-position-right page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Niki</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">天道酬勤</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-categories"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
    <link itemprop="mainEntityOfPage" href="https://gitee.com/shuhao/blog/2018/11/24/geth创建合约项目与合约交互/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Fang ShuHao">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/head.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Niki">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                创建合约项目与合约交互
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-11-24T09:56:53+08:00">
                2018-11-24
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/区块链/" itemprop="url" rel="index">
                    <span itemprop="name">区块链</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>前段时间了解了一下智能合约的开发，部署运行。本文中介一下前段时间的成果。<br><strong>如果存在某些纰漏还行各位大神指正批评</strong></p>
<h2 id="智能合约开发"><a href="#智能合约开发" class="headerlink" title="智能合约开发"></a>智能合约开发</h2><p>在智能合约的开发中，我选择的是Ethereum的solidity。当然还有其他的开发语言如：</p>
<h3 id="语言入门"><a href="#语言入门" class="headerlink" title="语言入门"></a>语言入门</h3><p>对于solidity语言的入门可以参照一下一些教程</p>
<ul>
<li><a href="https://solidity.readthedocs.io" target="_blank" rel="external">solidity的官方教程</a>。</li>
<li>etherrum提供了一套完整的实例项目。从<a href="https://ethereum.org/token" target="_blank" rel="external">发布自己的代币</a>，到<a href="https://ethereum.org/crowdsale" target="_blank" rel="external">众筹项目的开发</a>也是不错的参考教程。</li>
<li><a href="https://github.com/cyrusadkisson/solidity-baby-steps" target="_blank" rel="external">solidity的示例代码</a></li>
<li>还有一个github的项目<a href="https://github.com/OpenZeppelin/openzeppelin-solidity" target="_blank" rel="external">OpenZeppelin</a>也可以学习看下。</li>
</ul>
<h3 id="IDE选择"><a href="#IDE选择" class="headerlink" title="IDE选择"></a>IDE选择</h3><p>现在，学习一门语言一个好的IDE可谓事半功倍。现在也有许多IDE支持solidity。例如</p>
<ul>
<li>VSCode</li>
<li>sublime</li>
<li>intelli IDE<br>这些IDE都有相应的插件可供下载。<br>最后推荐一款在线的IDE：<a href="http://remix.ethereum.org" target="_blank" rel="external">remix</a>。非常方便，且功能非常强大。官方也推荐这款ide。在初学时，可以免去一些因为搭建环境而造成的学习障碍。当然这款ide也有<a href="https://github.com/ethereum/remix-ide" target="_blank" rel="external">离线版本</a>大家也可以下载到本地使用。</li>
</ul>
<h3 id="合约开发"><a href="#合约开发" class="headerlink" title="合约开发"></a>合约开发</h3><p>我们来开发一个简单的智能合约：HelloWorld<br><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">pragma solidity ^0.4.18;</span><br><span class="line"></span><br><span class="line">contract HelloWorld&#123;</span><br><span class="line">    string public name;</span><br><span class="line">    </span><br><span class="line">    function hello() public returns(string)&#123;</span><br><span class="line">        return &quot;HelloWorld!&quot;;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    function setName(string youName) public &#123;</span><br><span class="line">        name = youName;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    function sayHello() returns(string)&#123;</span><br><span class="line">        return stringAdd(&quot;hello &quot;, name);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    function stringAdd(string a, string b) internal returns(string)&#123;</span><br><span class="line">        bytes memory a_ = bytes(a);</span><br><span class="line">        bytes memory b_ = bytes(b);</span><br><span class="line">        bytes memory res = new bytes(a_.length + b_.length);</span><br><span class="line">        for(uint i=0; i&lt; a_.length; i++)&#123;</span><br><span class="line">            res[i] = a_[i];</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        for(uint j = 0; j&lt;b_.length; j++)&#123;</span><br><span class="line">            res[a_.length + j] = b_[j];</span><br><span class="line">        &#125;</span><br><span class="line">        return string(res);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>这是一个简单的智能合约，对外总共有三个方法hello、setName、sayHello。</p>
<ul>
<li>hello方法返回字符串 HelloWorld</li>
<li>setName方法为合约中的状态变量name赋值</li>
<li>sayHello方法返回hello+name。<strong>由于solidity中的字符串都是byte数组，所以无法使用“+”来拼接字符串</strong></li>
</ul>
<h2 id="智能合约部署"><a href="#智能合约部署" class="headerlink" title="智能合约部署"></a>智能合约部署</h2><p>智能合约开发完成后，需要发布到Ethereum的区块链网络中运行。目前Ethereum存在如下几个主要的区块链网络</p>
<ul>
<li>Main Ethereum Network<br>区块链的主网。类似于线上环境。发布合约到该网络需要ether</li>
<li>Ropsten Test Network：支持geth和Parity客户端</li>
<li>Kovan Test Network：只支持Parity客户端</li>
<li>Rinkeby Test NetWork：只支持geth客户端<br><strong>对于开发，建议你使用Rinkeby或KoVan测试链。这是因为他们使用的工作量证明POA共识机制，确保交易和块能够一致并及时的创建。Ropsten测试链，虽然最接近公有链(Mainnet)，但是因为它使用的工作量证明是POW共识机制，过去已受到攻击，对以太坊开发人员来说往往有更多的问题。</strong><br>上面三个网络为测试环境的网络，发布合约也需要ether。但是这些测试网络的ether可以在相应的网站免费获取。<br><a href="https://faucet.ropsten.be/" target="_blank" rel="external">获取ropsten环境的ether</a><br><a href="https://github.com/kovan-testnet/faucet" target="_blank" rel="external">Kovan测试链</a><br>这些环境便于在我们发布合约到真实环境之前进行验证，而不浪费我们的以太币。<br>当然，除了这些环境我们还可以发布到我们自己搭建的私有网络上。一般我们通过Ganache搭建我们的私有环境</li>
</ul>
<h3 id="智能合约编译发布"><a href="#智能合约编译发布" class="headerlink" title="智能合约编译发布"></a>智能合约编译发布</h3><h4 id="remix"><a href="#remix" class="headerlink" title="remix"></a>remix</h4><ol>
<li><p>编译<br>我们通过remix在线浏览器编译我们编写好的智能合约</p>
<img src="/blog/images/区块链/smart_contract/remix_compile.png">
<p>如果我们的智能合约检查通过，点击【Start to compile】完成合约的编译。</p>
</li>
<li><p>发布到Ropsten<br>这里我们需要另一个工具MetaMask钱包，这个钱包方便管理我们的账号<br><strong>MetaMask是一个浏览器插件，目前支持Firefox  , Chrome， Opena</strong><br>关于MetaMaskd 使用可以<a href="http://www.chaindesk.cn/witbook/article/4" target="_blank" rel="external">阅读</a></p>
</li>
</ol>
<p>在remix工具栏的run选项卡中发布我们的智能合约。首先，将Environment 选择Injected Web3.然后remix会连接浏览器中打开的MetaMask。Account自动选择MetaMask当前的账号。<br>点击Deploy。<br><img src="/blog/images/区块链/smart_contract/remix_deploy_1.png"></p>
<p>如图：MetaMask会弹出一个交易确认框，里面包括发送该合约需要的Gas（燃料）确保当前账户有足够的Gas点击CONFIRM就发布智能合约。<br><img src="/blog/images/区块链/smart_contract/remix_deploy_2.png"></p>
<p>回到MetaMask,可以看到，当前的交易正在等待一个矿工将其写进区块中。到那个时候，我们的合约就真正在以太坊的区块链网络中运行了。<br>等待的时间大致几分钟，主要跟你提供的Gas有关Gas越高，则矿工会优先确认你的交易，将其写进区块。<br><img src="/blog/images/区块链/smart_contract/remix_deploy_pending.png"></p>
<img src="/blog/images/区块链/smart_contract/remix_deplou.png">
<p>通过点击交易记录右上角的图标，我们也可以去<a href="https://ropsten.etherscan.io/tx/0xff86ac4d3f07053396f3b1b345bada4ab8d1fd84a05c8de5133bd168dda74e01" target="_blank" rel="external">Ethereum</a>查看该交易的区块信息<br><img src="/blog/images/区块链/smart_contract/remix_deploy_info.png"></p>
<h4 id="geth"><a href="#geth" class="headerlink" title="geth"></a>geth</h4><p>上面介绍了通过remix来发布我们的合约，另外我们也可以通过geth来发布</p>
<ul>
<li>geth介绍<br>geth是Ethereum协议的一个命令行客户端。该客户端允许我们搭建自己的区块链，创建此账号，转账，查询余额，部署智能合约<br>geth的一些命令可以查看其<a href="https://github.com/ethereum/go-ethereum/wiki" target="_blank" rel="external">文档</a></li>
</ul>
<h2 id="与智能合约交互"><a href="#与智能合约交互" class="headerlink" title="与智能合约交互"></a>与智能合约交互</h2><p>这里我们选择web3js来与智能合约进行交互。web3js类似于<strong>使用js与Ethereum进行交互</strong>的接口。<br>目前web3js有<a href="https://github.com/ethereum/wiki/wiki/JavaScript-API" target="_blank" rel="external">0.2x.x</a>与<a href="http://web3js.readthedocs.io/en/1.0/index.html" target="_blank" rel="external">1.x</a>两个版本两个版本的语法还略有差别<br>关于web3j的使用，可以参考其<a href="https://web3js.readthedocs.io" target="_blank" rel="external">文档</a><br>再提一句：也有java版本的接口<a href="https://web3j.readthedocs.io/en/latest/" target="_blank" rel="external">web3j</a></p>
<h3 id="连接测试网络Ropsten"><a href="#连接测试网络Ropsten" class="headerlink" title="连接测试网络Ropsten"></a>连接测试网络Ropsten</h3><p>我们之前将我们的智能合约发布到Ropsten环境。首先我们需要连接到该环境.</p>
<ol>
<li><p>安装依赖模块<br>首先保证安装了node、npm。然后安装ethereum依赖的模块</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm -g install web3</span><br><span class="line"></span><br><span class="line">npm -g install ethereumjs-util</span><br><span class="line"></span><br><span class="line">npm -g install ethereumjs-tx</span><br><span class="line"></span><br><span class="line">npm -个installethereumjs-wallet</span><br></pre></td></tr></table></figure>
</li>
<li><p>连接测试网路</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> Web3 = <span class="built_in">require</span>(<span class="string">"web3"</span>)</span><br><span class="line"><span class="keyword">var</span> web3 = <span class="keyword">new</span> Web3(Web3.givenProvider || <span class="string">'https://ropsten.infura.io/&lt;you  key</span></span><br><span class="line"><span class="string">&gt;'</span>)</span><br></pre></td></tr></table></figure>
</li>
</ol>
<img src="/blog/images/区块链/smart_contract/use_infura.png">
<ol>
<li><p>解锁账号,获得账户余额<br>我们创建账号之后，会保存我们的私钥，下面如何通过私钥获得我们的账号信息！</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 账户信息</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">countInfo</span>(<span class="params">privateKey</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 通过私钥解锁账户</span></span><br><span class="line">    <span class="keyword">let</span> account = web3.eth.accounts.privateKeyToAccount(privateKey)</span><br><span class="line">    <span class="built_in">console</span>.info(<span class="string">"账户信息："</span>, account)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 通过私钥获取账户余额</span></span><br><span class="line">    <span class="keyword">let</span> balnance = web3.eth.getBalance(account.address)</span><br><span class="line">    balnance.then(<span class="function"><span class="keyword">function</span> (<span class="params">d</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.info(<span class="string">"账户余额="</span>, d)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">return</span> account.address</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>与合约交互<br>简单的方法调用我们采用call的方式</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 调用智能合约方法,该调用为比较简单的方法调用，该方法在Eth的VM中执行，且该交易不会加入到区块链中</span></span><br><span class="line"><span class="comment"> * 方法的返回值未promise对象，异步返回值为合约方法的返回值</span></span><br><span class="line"><span class="comment"> *  */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">callContractMethad</span>(<span class="params">address, methodHash</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> res = web3.eth.call(&#123;</span><br><span class="line">        to: address,</span><br><span class="line">        data: <span class="string">"0x"</span> + methodHash</span><br><span class="line">    &#125;)</span><br><span class="line">    res.then(<span class="built_in">console</span>.log)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>以太坊中有一个ABI协议，会对方法的调用，传参，出参进行协议的转换，<a href="https://bitshuo.com/topic/58b41a0408d6a0f32a5bc0b7" target="_blank" rel="external">详情查看</a>。或者<a href="https://solidity.readthedocs.io/en/latest/abi-spec.html" target="_blank" rel="external">官方解释</a>所以我们必须对调用的方法进行编码。以太坊也提供了相关的工具类.具体参考<br>：<br><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * ABI协议计算方法的签名</span></span><br><span class="line"><span class="comment"> * @param  funName 方法描述，包括方法名以及参数类型列表</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">funHash</span>(<span class="params">funName</span>) </span>&#123;</span><br><span class="line">     <span class="keyword">let</span> methHash = web3.utils.sha3(funName).substr(<span class="number">2</span>, <span class="number">8</span>)</span><br><span class="line">    <span class="keyword">return</span> methHash</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过ABI加密方法</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">encodeFunctionSignature</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> funHash = web3.eth.abi.encodeFunctionSignature(</span><br><span class="line">        &#123;</span><br><span class="line">            name: <span class="string">'setName'</span>,</span><br><span class="line">            type:<span class="string">'function'</span>,</span><br><span class="line">            inputs:[</span><br><span class="line">                &#123;</span><br><span class="line">                    type:<span class="string">'string'</span>,</span><br><span class="line">                    name:<span class="string">'youName'</span></span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">        &#125;</span><br><span class="line">    )</span><br><span class="line">    <span class="keyword">return</span> funHash</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"计算方法签名1: "</span>+encodeFunctionSignature())</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"计算方法签名2: "</span>+web3.eth.abi.encodeFunctionSignature(<span class="string">"setName(string)"</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"计算方法签名3: "</span>+ funHash(<span class="string">"setName(string)"</span>))</span><br><span class="line"></span><br><span class="line">&gt;&gt;输出：</span><br><span class="line">计算方法签名<span class="number">1</span>: <span class="number">0xc47f0027</span></span><br><span class="line">计算方法签名<span class="number">2</span>: <span class="number">0xc47f0027</span></span><br><span class="line">计算方法签名<span class="number">3</span>: c47f0027</span><br></pre></td></tr></table></figure></p>
<p>三个方法都能计算方法通过ABI协议的签名。第一种比较简单，第二种比较详细。我们怎么验证我们的签名是否正确呢？我们可以在remixIDE中查看已经编译好的方法的Hash。通过图片可以看到我们计算的方法Hash值和remix IDE编译后的值一样。<br><img src="/blog/images/区块链/smart_contract/remix_method_hash.png"></p>
<p>调用方法。我们调用合约中的hello方法，返回一个string参数值 HelloWorld!<br><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 19ff1d21 是计算hello()方法的hash值</span></span><br><span class="line">callContractMethad(contractAddress, <span class="string">"19ff1d21"</span>)</span><br><span class="line"></span><br><span class="line">&gt;&gt; 输出：</span><br><span class="line"><span class="number">0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b48656c6c6f576f726c6421000000000000000000000000000000000000000000</span></span><br></pre></td></tr></table></figure></p>
<p>结果输出的是一串16进制的数据，刚有说到因为智能合约的入参和出参都通过ABI协议进行了编码。所以我们需要解码方法调用返回的参数。<br><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">// 解密合约通过ABI协议加密的返回值</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">decodeABIParam</span>(<span class="params">param</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> decodeParam = web3.eth.abi.decodeParameter(<span class="string">"string"</span>, param)</span><br><span class="line">    <span class="built_in">console</span>.info(<span class="string">"解密后的值："</span> + decodeParam)</span><br><span class="line">    <span class="keyword">return</span> decodeParam</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">decodeABIParam(<span class="string">"0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b48656c6c6f576f726c6421000000000000000000000000000000000000000000"</span>)</span><br><span class="line"></span><br><span class="line">&gt;&gt; 输出：</span><br><span class="line">解密后的值：HelloWorld!</span><br></pre></td></tr></table></figure></p>
<p>bingo得到了合约方法返回的正确值。</p>
<p>已经可以简单的与智能合约的交互。如果我们需要给智能合约发送交易呢？那就需要另一种调用方式了</p>
<blockquote>
<blockquote>
<p>参考<br><a href="https://medium.com/@chocolatetiger/smart-contract%E5%85%A5%E9%96%80%E9%96%8B%E7%99%BC%E6%95%99%E5%AD%B8-79ce5830ebf2" target="_blank" rel="external">https://medium.com/@chocolatetiger/smart-contract%E5%85%A5%E9%96%80%E9%96%8B%E7%99%BC%E6%95%99%E5%AD%B8-79ce5830ebf2</a><br><a href="https://blog.csdn.net/a394268045/article/details/79470221" target="_blank" rel="external">https://blog.csdn.net/a394268045/article/details/79470221</a></p>
</blockquote>
</blockquote>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/blog/tags/区块链/" rel="tag"># 区块链</a>
          
            <a href="/blog/tags/solidity/" rel="tag"># solidity</a>
          
            <a href="/blog/tags/智能合约/" rel="tag"># 智能合约</a>
          
        </div>
      

      
        
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/blog/2018/11/07/springboot创建Web项目/" rel="next" title="springboot创建Web项目">
                <i class="fa fa-chevron-left"></i> springboot创建Web项目
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/blog/2018/12/05/truffle和Ganache部署区块链/" rel="prev" title="truffle和Ganache部署区块链">
                truffle和Ganache部署区块链 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>

          
          </div>
          


          
  <div class="comments" id="comments">
    
      <div id="lv-container" data-id="city" data-uid="MTAyMC8zNjY5NS8xMzIzMA=="></div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/blog/images/head.jpg"
               alt="Fang ShuHao" />
          <p class="site-author-name" itemprop="name">Fang ShuHao</p>
           
              <p class="site-description motion-element" itemprop="description"></p>
          
        </div>
        <nav class="site-state motion-element">
        
          
            <div class="site-state-item site-state-posts">
              <a href="/blog/archives">
                <span class="site-state-item-count">135</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-categories">
              <a href="/blog/categories">
                <span class="site-state-item-count">35</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/blog/tags">
                <span class="site-state-item-count">93</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#智能合约开发"><span class="nav-number">1.</span> <span class="nav-text">智能合约开发</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#语言入门"><span class="nav-number">1.1.</span> <span class="nav-text">语言入门</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#IDE选择"><span class="nav-number">1.2.</span> <span class="nav-text">IDE选择</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#合约开发"><span class="nav-number">1.3.</span> <span class="nav-text">合约开发</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#智能合约部署"><span class="nav-number">2.</span> <span class="nav-text">智能合约部署</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#智能合约编译发布"><span class="nav-number">2.1.</span> <span class="nav-text">智能合约编译发布</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#remix"><span class="nav-number">2.1.1.</span> <span class="nav-text">remix</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#geth"><span class="nav-number">2.1.2.</span> <span class="nav-text">geth</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#与智能合约交互"><span class="nav-number">3.</span> <span class="nav-text">与智能合约交互</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#连接测试网络Ropsten"><span class="nav-number">3.1.</span> <span class="nav-text">连接测试网络Ropsten</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Fang ShuHao</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Mist
  </a>
</div>


        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    
    
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  




  
  <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.0"></script>



  
  

  
  <script type="text/javascript" src="/blog/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/blog/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.0"></script>



  



  




	





  





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  



  
  

  

  

  

  


  

</body>
</html>
